using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Xfinity.Entities;

namespace Xfinity.AI
{
    /// <summary>
    /// A propertional-integral-derivative feedback controller.
    /// </summary>
    public class PidController : LogicalEntity
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="PidController"/> class.
        /// </summary>
        /// <param name="proportionalTerm">The proportional term.</param>
        /// <param name="derivativeTerm">The derivative term.</param>
        /// <param name="integralTerm">The integral term.</param>
        /// <param name="name">The name.</param>
        /// <param name="game">The game.</param>
        public PidController(float proportionalTerm, float derivativeTerm, float integralTerm, string name, Game game)
            : base(name, game)
        {
            this.proportionalTerm = proportionalTerm;
            this.derivativeTerm = derivativeTerm;
            this.integralTerm = integralTerm;
            ErrorHistory = 5;
        }
        private float proportionalTerm;

        /// <summary>
        /// Gets or sets the proportional term.
        /// </summary>
        /// <value>The proportional term.</value>
        public float ProportionalTerm
        {
            get { return proportionalTerm; }
            set { proportionalTerm = value; }
        }
        private float derivativeTerm;

        /// <summary>
        /// Gets or sets the derivative term.
        /// </summary>
        /// <value>The derivative term.</value>
        public float DerivativeTerm
        {
            get { return derivativeTerm; }
            set { derivativeTerm = value; }
        }
        private float integralTerm;

        /// <summary>
        /// Gets or sets the integral term.
        /// </summary>
        /// <value>The integral term.</value>
        public float IntegralTerm
        {
            get { return integralTerm; }
            set { integralTerm = value; }
        }

        Queue<float> pastErrors;

        private int errorHistory;

        /// <summary>
        /// Gets or sets the error history.
        /// </summary>
        /// <value>The error history.</value>
        public int ErrorHistory
        {
            get { return errorHistory; }
            set { errorHistory = value; pastErrors = new Queue<float>(errorHistory); }
        }
    }
}
